﻿//This is the game
using System;
using System.Threading;
using System.Collections.Generic;

class TheGame
{
    const int MaxHeight = 50;
    const int MaxWidth = 80;


    static int lives = 3; //count of lives of the player

    static List<List<int>> enemies = new List<List<int>>(); //list to keep enemy coordinates
    static List<List<int>> shots = new List<List<int>>(); //list to keep shots coordinates
    static string enemySymbol = "*V*";

    static Random rand = new Random();

    public static SpaceShip MyShip = new SpaceShip();

    static void Main(string[] args) //I've moved this method on top I think this way is more convenient - d.m.
    {
        Console.BufferHeight = Console.WindowHeight = MaxHeight;
        Console.BufferWidth = Console.WindowWidth = MaxWidth;
        MyShip.GoToStartPosition();

        int steps = 0;
        int enemiesPause = 3;

        while (lives > 0)
        {
            if (steps % enemiesPause == 0)
            {
                GenerateEnemy();
                UpdateEnemies();
                EnemiesVsPlayerCollisionsHandling(); 
                steps = 0;
            }
            
            steps++;
            MoveShip();
            PrintLives();
            DrawEnemies();
            EnemiesOutsideBounds(); //Removes all enemies that are outside bounds
            

            Thread.Sleep(200); //HINT: Make different speeds
            Console.Clear();
        }

        //Game over screen
        Console.SetCursorPosition(MaxWidth / 2 - 6, MaxHeight / 2);
        Console.WriteLine("GAME OVER");
        Console.Read();
    }

    private static void EnemiesOutsideBounds()
    {
        for (int i = 0; i < enemies.Count; i++)
        {
            List<int> currentEnemy = enemies[i];
            int currEnemyY = currentEnemy[1];

            if (currEnemyY > MaxHeight)
            {
                enemies.Remove(currentEnemy);
            }
        }
    }

    private static void PrintLives()
    {
        Console.SetCursorPosition(1,0);
        Console.ForegroundColor = ConsoleColor.White;
        Console.Write(lives);
    }

    private static void EnemiesVsPlayerCollisionsHandling()
    {
        for (int i = 0; i < enemies.Count; i++)
        {
            List<int> currentEnemy = enemies[i];
            int enemyXpos = currentEnemy[0];
            int enemyYpos = currentEnemy[1];

            if ((MyShip.PositionX >= enemyXpos && MyShip.PositionX <= enemyXpos + enemySymbol.Length - 1 && 
                MyShip.PositionY - 1 == enemyYpos) ||
                (MyShip.PositionX == enemyXpos + enemySymbol.Length - 1 &&
                MyShip.PositionY == enemyYpos)) //enemy hit the spaceship TODO: check for hit at the side of the ship
            {
                //Console.Beep(1000,30);  //sound when hit
                lives--;
                enemies.Remove(currentEnemy);
            }
        }
    }


    private static void DrawEnemies()
    {
        foreach (var enemy in enemies)
        {
            ConsoleColor enemyColor = ConsoleColor.DarkGreen;
            DrawEnemy(enemy, enemySymbol, enemyColor);
        }

    }

    private static void DrawEnemy(List<int> enemy, string enemySymbol, ConsoleColor enemyColor)
    {
        Console.SetCursorPosition(enemy[0], enemy[1]);
        Console.ForegroundColor = enemyColor;
        Console.WriteLine(enemySymbol);
    }

    private static void GenerateEnemy()
    {
        int random = rand.Next(1, MaxWidth - 2);
        List<int> randomCoordinates = new List<int>() { random, 1 };
        enemies.Add(randomCoordinates);
    }

    private static void UpdateEnemies() // moves enemy downside
    {
        for (int i = 0; i < enemies.Count; i++) //moves one row down
        {
            enemies[i][1] = enemies[i][1] + 1;
        }

        int index = -1;

        for (int i = 0; i < enemies.Count; i++) //marks enemy to remove
        {
            if (enemies[i][1] >= MaxHeight)
            {
                index = i;
                break;
            }
        }

        if (index != -1)//we found enemy that is out of the boundaries and now we have to remove it
        {
            enemies.RemoveAt(index);
        }
    }

    public class SpaceShip
    {
        public int PositionX = 0;
        public int PositionY = 0;
        public string FrontShip = "|";
        public string BackShip = "o0o";

        public void GoToStartPosition()
        {
            this.PositionX = MaxWidth / 2 - 1;
            this.PositionY = MaxHeight - 2;
        }
        public void MoveLeft()
        {
            this.PositionX--;
        }
        public void MoveRight()
        {
            this.PositionX++;
        }
        public void MoveUp()
        {
            this.PositionY--;
        }
        public void MoveDown()
        {
            this.PositionY++;
        }
    }

    static void DrawShip(int posX, int posY, string line1, string line2, ConsoleColor color)
    {
        Console.SetCursorPosition(posX, posY - 1);
        Console.ForegroundColor = color;
        Console.Write(line1);
        Console.SetCursorPosition(posX - 1, posY);
        Console.Write(line2);

    }

    static void MoveShip()
    {
        //while (true) //there is already one 'while' loop
        //{
            DrawShip(MyShip.PositionX, MyShip.PositionY, MyShip.FrontShip, MyShip.BackShip, ConsoleColor.Red);
            if (Console.KeyAvailable)
            {
                ConsoleKeyInfo pressedKey = Console.ReadKey(true);

                while (Console.KeyAvailable)
                {
                    Console.ReadKey(true);
                }

                if (pressedKey.Key == ConsoleKey.LeftArrow)
                {
                    if (MyShip.PositionX - 1 > 0)
                    {
                        MyShip.MoveLeft();
                    }
                }

                if (pressedKey.Key == ConsoleKey.RightArrow)
                {
                    if (MyShip.PositionX + 2 < MaxWidth)
                    {
                        MyShip.MoveRight();
                    }
                }

                if (pressedKey.Key == ConsoleKey.UpArrow)
                {
                    if (MyShip.PositionY - 1 > 0)
                    {
                        MyShip.MoveUp();
                    }
                }
                if (pressedKey.Key == ConsoleKey.DownArrow)
                {
                    if (MyShip.PositionY + 2 < MaxHeight)
                    {
                        MyShip.MoveDown();
                    }
                }
                //Thread.Sleep(60); //I've moved it to the bottom of the common 'while' loop and I've increased the value - d.m.
                //Console.Clear(); //when uncommented removes enemies from the screen!
                //DrawShip(MyShip.PositionX, MyShip.PositionY, MyShip.FrontShip, MyShip.BackShip, ConsoleColor.Red); I've moved this method at the top 
                //in order to show the ship as soon as the game begins
            }
       //}
    }
}

